<template>
	<view class="chatInterface">
		<!-- <ul v-for="(item ,index) in messages" v-bind:key="index +'itemMessage'">
      <li>
        <text>{{item.user}} says </text>
        <text class="mes" v-if="item.type == 'text'" v-html="renderTextMessage(item.message)"></text>
      </li>
    </ul> -->
    <view :class="(!this.more.show && !this.emoji.show) ? 'scroll-view' : 'scroll-view pb'">
      <view v-for="(item,index) in messages" :key="index+item.message">
        <view class="message-item" :class="{'self' : item.user == userName}">
          <view class="avatar" v-if="item.user != userName">
            <!-- 好友 -->
            <image src="../../static/images/Avatar-1.png"></image>
          </view>
          <view class="avatar" v-else>
            <!-- 自己 -->
            <image src="../../static/images/Avatar-2.png"></image>
          </view>
          <view v-if="item.type == 'text'" :class="item.user == userName ? 'content' : 'contents'">
            <view v-html="renderTextMessage(item.message)"></view>
          </view>
          <view v-if="item.type == 'img'" class="content-img">
            <image class="image-content" :src="item.message" :data-url="item.message" @click="showImageFullScreen" mode="widthFix"></image>
          </view>
        </view>
      </view>
    </view>
		<view class="home">
			<view class="action">
				<view :class="[audio.visible ? 'record-icon record-open':'record-icon']" @click="switchAudioKeyboard"></view>
				<view class="record-input" @touchstart="onRecordStart" @touchend="onRecordEnd" v-if="audio.visible" >{{audio.recording ? '松开发送' : '按住录音'}}</view>
				<view class="message-input" v-else>
					<input type="text" maxlength="700" placeholder="发送消息" :focus='setFocus' v-model="content" @focus="messageInputFocusin">
				</view>
				<view class="file-icon emoji-icon" @click="showEmoji"></view>
				<view v-if="!content" class="file-icon more-icon" @click="showMore"></view>
				<span v-if="content" class="send-message-btn" @click="sendAll">发送</span>
			</view>
			<!--展示表情列表-->
			<view class="action-bottom" v-if="emoji.show" style="flex-wrap: wrap;overflow: auto">
				<image class="emoji-item" v-for="(emojiItem, emojiKey, index) in emoji.map" :key="index" :src="emoji.url + emojiItem" @click="selectEmoji(emojiKey)"></image>
			</view>
			<!--更多-->
			<view class="action-bottom" v-if="more.show">
				<view class="more-item" @click="sendImage">
					<image src="../../static/images/tupian.png"></image>
					<text>图片</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import * as signalR from "../../static/signalr";
	import EmojiDecoder from '../../components/emoji/EmojiDecoder'
	const recorderManager = uni.getRecorderManager();
	export default {
		data() {
			let emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/';
			let emojiMap = {
				'[ok]': 'emoji_1@2x.png',
				'[么么哒]': 'emoji_3@2x.png',
				'[乒乓]': 'emoji_4@2x.png',
				'[便便]': 'emoji_5@2x.png',
				'[信封]': 'emoji_6@2x.png',
				'[偷笑]': 'emoji_7@2x.png',
				'[傲慢]': 'emoji_8@2x.png',
				'[再见]': 'emoji_9@2x.png',
				'[流汗]': 'emoji_10@2x.png',
				'[凋谢]': 'emoji_11@2x.png',
				'[勾引]': 'emoji_14@2x.png',
				'[鼻涕]': 'emoji_15@2x.png',
				'[发抖]': 'emoji_16@2x.png',
				'[可怜]': 'emoji_17@2x.png',
				'[愉快]': 'emoji_18@2x.png',
				'[右哼哼]': 'emoji_19@2x.png',
				'[转圈]': 'emoji_20@2x.png',
				'[吐]': 'emoji_22@2x.png',
				'[咒骂]': 'emoji_24@2x.png',
				'[咖啡]': 'emoji_25@2x.png',
				'[啤酒]': 'emoji_26@2x.png',
				'[嘘]': 'emoji_27@2x.png'
			};
			return {
				user: "", //用户
				message: "", //消息
				connection: "", //signalr连接
				messages: [], //返回消息
				audio : {
					//语音录音中
					recording : false,
					//录音按钮展示
					visible : false
				},
				more : {//更多按钮
					show : false
				},
				content: '',
				//定义表情列表
				emoji : {
					url : emojiUrl,
					map : emojiMap,
					show: false,
					decoder:  new EmojiDecoder(emojiUrl, emojiMap),
				},
				userName: '', // 登录获取的用户名
				type: 'text', // 用来判断发送的类型text文字+表情
				setFocus: false // input聚焦
			}
		},
		onLoad() {
			this.messages = uni.getStorageSync('messages')
      this.scrollToBottom()
			let self = this;
			this.userName = uni.getStorageSync('currentUser')
			this.connection = new signalR.HubConnectionBuilder()
				.withUrl("https://localhost:44314/chathub", {
					skipNegotiation: true,
					transport: signalR.HttpTransportType.WebSockets
				})
				.configureLogging(signalR.LogLevel.Information)
				.build();
			this.connection.on("ReceiveMessage", function(user, message) {
				if (self.type == 'text') {
					self.messages.push({ user, message, type:'text' });
				} else if (self.type == 'img') {
					self.messages.push({ user, message, type: 'img' });
					self.type = 'text'
				}
				// self.messages.push({ user, message, type });
				console.log(self.messages)
				uni.setStorageSync('messages', self.messages)
			});
			this.connection.on("ReceiveCaller", function(message) {
				let user = "自己"; //这里为了push不报错，我就弄了一个默认值。
				self.messages.push({ user, message });
			});
			this.connection.start();
		},
		methods:{
			//语音录制按钮和键盘输入的切换
			switchAudioKeyboard() {
				this.audio.visible = !this.audio.visible;
				this.content = '' // 清除输入框文字
				this.emoji.show = false
				this.more.show = false
				if(uni.authorize){
					uni.authorize({
						scope : 'scope.record'
					})
				}
			},
			onRecordStart () {
				try{
					recorderManager.start();
				}catch(e){
					uni.showModal({
						title: '录音错误',
						content : '请在app和小程序端体验录音，Uni官方明确H5不支持getRecorderManager, 详情查看Uni官方文档'
					});
				}
			},
			onRecordEnd () {
				try{
					recorderManager.stop();
				}catch(e){
					console.log(e)
				}
			},
			messageInputFocusin () {
				this.more.show = false;
				this.emoji.show = false
			},
			showEmoji () {
				this.emoji.show = !this.emoji.show;
				this.more.show = false;
				this.audio.visible = false
				if (this.emoji.show) {
					this.scrollToBottom()
				}
			},
			// 选表情
			selectEmoji (emojiKey) {
				this.content += emojiKey
			},
			// 上传图片逻辑开始---------------------------------
			showMore () {
				this.more.show = !this.more.show;
				this.emoji.show = false
				this.audio.visible = false
				if (this.more.show) {
					this.scrollToBottom()
				}
			},
			sendImage() {
				const self = this
				uni.chooseImage({
					count :1,
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					sourceType: ['album'], //从相册选择
					success: function (res) {
						// 图片转base64
						res.tempFiles.forEach((item, index) => {
							self.urlTobase64(res.tempFilePaths[index],item);
						})
					}
				});
			},
			// 图片转base64
			urlTobase64(url,item) {
				var itemname=item.name.split('.')[0];
				var itemtype=item.name.split('.')[1];
				var base64 ='';
				uni.request({
					url: url,
					method: 'GET',
					responseType: 'arraybuffer',
					success: res => {
						base64 = uni.arrayBufferToBase64(res.data); //把arraybuffer转成base64
						base64 = 'data:image/jpeg;base64,' + base64; //不加上这串字符，在页面无法显示
						var img = {
							"name":itemname,
							"size": item.size,
							"type": itemtype,
							"content": base64,
							url:url,
							new:true,
							state:-1,
						};
						console.log(img)
						this.more.show = false // 关闭上传图片
						this.message = img.url // 讲消息赋值为图片url
						this.type = 'img' // 用于显示图片
						this.sendAll()
					}
				});
			},
			showImageFullScreen (e) {
				var imagesUrl = [e.currentTarget.dataset.url];
				uni.previewImage({
					urls: imagesUrl
				});
			},
			// 上传图片逻辑结束-------------------------------
			scrollToBottom() {
				this.$nextTick(function(){
          setTimeout(() => {
            uni.pageScrollTo({
              scrollTop: 99999,
              duration: 0
            })
          }, 200)
				});
			},
			//发送消息
			sendAll: function() {
				if (this.type == 'text') {
					this.connection.invoke("SendMessage", this.userName, this.content).catch(function(err) {
						return err
					});
				} else if (this.type == 'img') {
					this.connection.invoke("SendMessage", this.userName, this.message).catch(function(err) {
						return err
					});
				}
				this.content = '' // 清空输入框文字
				this.emoji.show = false // 隐藏表情
				setTimeout(() => {
					this.setFocus = true // input聚焦
				},0)
        this.scrollToBottom()
			},
			// 信息回显
			//渲染文本消息，如果包含表情，替换为图片
			//todo:本不需要该方法，可以在标签里完成，但小程序有兼容性问题，被迫这样实现
			renderTextMessage(message) {
				return '<span class="text-content">' + this.emoji.decoder.decode(message) + '</span>'
			},
		}
	}
</script>

<style lang="scss" scoped>
	page {
		background-color: #ededed;
	}

	.scroll-view{
		padding-left: 20rpx;
		padding-right: 20rpx;
		box-sizing: border-box;
		padding-bottom: 120rpx;
	}
	.pb {
		padding-bottom: 300rpx;
	}
	.message-item{
		// max-height: 400rpx;
		margin-top: 30rpx;
		margin-bottom: 30rpx;
		overflow: hidden;
		display: flex;
	}
	.self{
		overflow: hidden;
		display: flex;
		justify-content: flex-start;
		flex-direction: row-reverse;
		padding-left: 100rpx;
	}
	.avatar{
		width: 80rpx;
		height: 80rpx;
		margin-right:20rpx ;
		flex-shrink: 0;
		flex-grow: 0;
	}
	.avatar image{
		width: 100%;
		height: 100%;
	}
	.self .avatar{
		margin-left: 20rpx;
		margin-right: 0;
	}
	.content{
		font-size: 32rpx;
		line-height: 44rpx;
		display: flex;
		align-items: center;
		justify-content: right;
		background: #94ed6d;
		padding: 10rpx 30rpx;
		border-radius: 10rpx;
		color: #091d04;
		z-index: 99;
		position: relative;
	}
	.contents{
		font-size: 32rpx;
		line-height: 44rpx;
		display: flex;
		align-items: center;
		justify-content: right;
		background: #fff;
		padding: 10rpx 30rpx;
		border-radius: 10rpx;
		color: #091d04;
		z-index: 99;
		position: relative;
	}
	.content::before {
		position: absolute;
		z-index: 9;
		position: absolute;
		content: '';
		right: -14rpx;
		top: 35rpx;
		width: 0;
		height: 0;
		border-left: solid 10rpx transparent;
		border-right: solid 10rpx transparent;
		border-bottom: solid 10rpx #94ed6d;
		transform: rotate(90deg);
	}
	.contents::before {
		position: absolute;
		z-index: 9;
		position: absolute;
		content: '';
		left: -14rpx;
		top: 35rpx;
		width: 0;
		height: 0;
		border-left: solid 10rpx transparent;
		border-right: solid 10rpx transparent;
		border-bottom: solid 10rpx #fff;
		transform: rotate(270deg);
	}
	.content-img{
		display: flex;
		align-items: center;
		justify-content: right;
		background: #fff;
		border-radius: 10rpx;
		z-index: 0;
		padding: 10rpx;
		position: relative;
	}
	.image-content{
		padding: 0rpx;
		border-radius: 12rpx;
		width: 200rpx;
		height: 200rpx;
		z-index: -1;
	}





	.home {
		display: flex;
		backdrop-filter: blur(0.27rpx);
		width: 100%;
		position: fixed;
		bottom: 96rpx;
		left: 0;
		flex-direction: column;
		background-color: #FFFFFF;
		z-index: 9999;
	}
	.action {
		display: flex;
		padding: 22rpx 0;
		// backdrop-filter: blur(0.27rem);
		height: 120rpx;
		background:#f7f7f7;
		width: 100%;
	}
	.record-icon {
		font-size: 32rpx;
		width: 80rpx;
		height: 80rpx;
		line-height: 80rpx;
		text-align: center;
		background: url("../../static/images/record-appearance-icon.png") no-repeat center;
		background-size: 60%;
		-webkit-tap-highlight-color:rgba(0,0,0,0);
	}
	.record-open {
		background: url("../../static/images/jianpan.png") no-repeat center;
		background-size: 70%;
		-webkit-tap-highlight-color:rgba(0,0,0,0);
	}
	.record-input {
		width: 499rpx;
		height: 80rpx;
		line-height: 80rpx;
		border-radius: 12rpx;
		font-size: 28rpx;
		background: #cccccc;
		color: #ffffff;
		text-align: center;
	}
	.message-input{
		border-radius: 12rpx;
		background: #ffffff;
		height: 80rpx;
	}
	.message-input input{
		width: 480rpx;
		height: 80rpx;
		line-height: 80rpx;
		padding-left: 20rpx;
		font-size: 28rpx;
	}
	.file-icon{
		background: url("../../static/images/video.png") no-repeat center;
		background-size: 70%;
		color: #9D9D9D;
		position: relative;
		width:80rpx;
		height: 80rpx;
		line-height: 80rpx;
		-webkit-tap-highlight-color:rgba(0,0,0,0);
	}
	.emoji-icon{
		background: url("../../static/images/emoji.png") no-repeat center;
		background-size: 70%;
	}
	.more-icon{
		background: url("../../static/images/more.png") no-repeat center;
		background-size: 70%;
	}
	.send-message-btn{
		font-size: 36rpx;
		width: 80rpx;
		line-height: 80rpx;
		color:#000000 ;
	}
	.action-bottom{
		height: 200rpx;
		width:100%;
		padding: 20rpx;
		box-sizing: border-box;
		display: flex;
	}
	.action-bottom image{
		width:60rpx;
		height: 60rpx;
	}
	.more-item{
		display: flex;
		flex-direction: column;
		width: 150rpx;
		height: 150rpx;
		margin-right: 20rpx;
		align-items: center;
	}
	.more-item image{
		height: 100rpx;
		width: 100rpx;
	}
	.more-item text{
		font-size: 20rpx;
		text-align: center;
		line-height: 50rpx;
	}

	.chatInterface /deep/ .text-content img {
		vertical-align: bottom!important;
	}
</style>
